# https://gitee.com/yueyinqiu5990/tj12413601/blob/master/assignment1/question2/calculators/trapezoidal_method.py
import typing

from question2.integration_calculator import Integration1dCalculatorAdaptive
from question2.integration_problem import IntegrationProblem1d


class TrapezoidalMethod(Integration1dCalculatorAdaptive):
    def _generate_steps_endlessly(
            self,
            problem: IntegrationProblem1d) \
            -> typing.Generator[float, None, None]:
        lower = problem.lower_limit()
        length = problem.upper_limit() - problem.lower_limit()
        function = problem.integrand()
        result = (function(lower) + function(lower + length)) * length / 2
        for trapezoid_count in Integration1dCalculatorAdaptive.endless_range(2):
            yield result
            trapezoid_height = length / trapezoid_count
            new_result = 0
            for trapezoid_index in range(1, trapezoid_count, 2):
                new_result += function(lower + trapezoid_height * trapezoid_index)
            new_result *= trapezoid_height
            result = result / 2 + new_result
